package com.winsdom.utils;

import lombok.extern.slf4j.Slf4j;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

@Slf4j
public class IpAddressUtil {

    /**
     * 获取当前机器的IP地址
     * @return 返回IP地址字符串
     */
    public static String getCurrentIpAddress() {
        try {
            // 优先获取非回环地址
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = networkInterfaces.nextElement();
                if (networkInterface.isLoopback() || !networkInterface.isUp()) {
                    continue;
                }

                Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress addr = addresses.nextElement();
                    if (addr.isLoopbackAddress()) continue;
                    if (addr.isSiteLocalAddress()) {
                        // 优先选择192.168开头的IP地址
                        String ipAddress = addr.getHostAddress();
                        if (ipAddress.startsWith("192.168")) {
                            return ipAddress;
                        }
                    }
                }
            }

            // 如果没有找到192.168开头的IP，再次遍历寻找任何站点本地地址
            networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = networkInterfaces.nextElement();
                if (networkInterface.isLoopback() || !networkInterface.isUp()) {
                    continue;
                }

                Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress addr = addresses.nextElement();
                    if (addr.isLoopbackAddress()) continue;
                    if (addr.isSiteLocalAddress()) {
                        return addr.getHostAddress();
                    }
                }
            }

            // 如果没有找到非回环地址，则返回本地回环地址
            return InetAddress.getLocalHost().getHostAddress();
        } catch (SocketException | UnknownHostException e) {
            log.error("获取IP地址失败", e);
            return "127.0.0.1";
        }
    }

    /**
     * 获取所有可用的IP地址
     * @return IP地址列表
     */
    public static List<String> getAllIpAddresses() {
        List<String> ipList = new ArrayList<>();
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = networkInterfaces.nextElement();
                if (networkInterface.isLoopback() || !networkInterface.isUp()) {
                    continue;
                }

                Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress addr = addresses.nextElement();
                    if (addr.isLoopbackAddress()) continue;
                    if (addr.getHostAddress().indexOf(':') < 0) { // 排除IPv6地址
                        ipList.add(addr.getHostAddress());
                    }
                }
            }
        } catch (SocketException e) {
            log.error("获取所有IP地址失败", e);
        }
        return ipList;
    }

    /**
     * 将IP地址转换为字节数组（二进制格式）
     * @param ipAddress IP地址字符串
     * @return 字节数组
     */
    public static byte[] ipToBytes(String ipAddress) {
        try {
            return InetAddress.getByName(ipAddress).getAddress();
        } catch (UnknownHostException e) {
            log.error("IP地址转换失败: " + ipAddress, e);
            return new byte[4];
        }
    }

    /**
     * 将字节数组（二进制格式）转换为IP地址字符串
     * @param bytes 字节数组
     * @return IP地址字符串
     */
    public static String bytesToIp(byte[] bytes) {
        try {
            return InetAddress.getByAddress(bytes).getHostAddress();
        } catch (UnknownHostException e) {
            log.error("字节数组转换IP地址失败", e);
            return "";
        }
    }

    /**
     * 获取当前IP地址的字节数组形式
     * @return 当前IP的字节数组
     */
    public static byte[] getCurrentIpBytes() {
        return ipToBytes(getCurrentIpAddress());
    }
}